package cn.lcsjsxy.yxc.annotation;

import java.util.ArrayList;

/**
 * 注解的使用
 * 1.理解Annotation
 * （1）JDK5.0新增的功能
 * （2）Annotation其实就是代码里的特殊标记，这些标记可以在编译，类加载，运行时被读取，并执行相应的处理。
 * 通过使用Annotation，程序员可以在不改变原有逻辑的情况下，在源文件处嵌入一些补充信息。代码分析工具、
 * 开发工具和部署工具可以通过这些信息进行验证或者进行部署
 * （3）Annotation可以像修饰符一样被使用，可以用于修饰包，构造器，方法，成员变量，参数，局部变量的声明，
 * 这些信息被保存在Annotation的"name=value"中
 * <p>
 * 2.Annotation的使用示例
 * 示例一：生成文档相关的注释
 * 示例二：在编译时进行格式检查(JDK内置的三个基本注解
 * 》@Override：限定重写父类方法，该注解只能用于方法
 * 》@Deprecated：用于表示所修饰的元素（类，方法等）已过时。通常是因为所修饰的结构危险或存在更好的选择
 * 》@SuppressWarnings：抑制编译器警告
 * 示例三：跟踪代码依赖性，实现替代配置文件的功能
 * <p>
 * 3.如何自定义注解:参照SuppressWarnings
 * (1)注解声明为@interface
 * (2)内部定义成员，通常使用value表示
 * (3)可以指定成员的默认值，使用default定义
 * (4)如果自定义注解没有成员，表明是一个标识作用
 * <p>
 * 如果注解有成员，在使用注解时，需要指定成员的值
 * 自定义注解必须配上注释的信息处理流程(使用反射)才有意义
 * 自定义注解通常都会指明两个元注解：Retention、Target
 * <p>
 * 4.jdk 提供的四种元注解
 * 元注解：对现有的注解进行解释说明的注解
 * 》Retention:指定所修饰的Annotation的生命周期：SOURCE\CLASS(默认行为)\RUNTIME
 * 只有声明为RUNTIME声明周期的注释，才能通过反射获取
 * 》Target:用于指定被修饰的Annotation，能用于修饰哪些程序元素
 * 》Documented:表示所修饰的注解在被javadoc解析时，保留下来。
 * 》Inherited
 * <p>
 * 5.通过反射获取注解信息
 * <p>
 * 6.JDK8中注释的新特性：可重复注解、类型注解
 * 6.1可重复注解:
 * （1）在MyAnnotation上声明@Repeatable，成员值为MyAnnotation.class
 * （2）MyAnnotation的Target和Retention和MyAnnotations相同
 *
 * 6.2类型注解
 * ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中(如：泛型声明)
 * ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中
 */
public class AnnotationTest {
    public static void main(String[] args) {
        Student student = new Student();
        student.shou();

        @SuppressWarnings("unused")  //抑制编译器警告
        int num = 10;
    }
}

@MyAnnotations({@MyAnnotation(value = "hi"), @MyAnnotation(value = "hello")})
class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void walk() {
        System.out.println("走路");
    }

    public void eat() {
        System.out.println("吃饭");
    }
}

interface Info {
    void shou();
}

class Student extends Person implements Info {
    @Override  //注解  编译时校验方法是否为重写的方法
    public void walk() {
        System.out.println("学生走路");
    }

    @Deprecated  //注解 表示过时的（类，方法，属性）  加上后用的时候会提示为过时的
    public void shou() {

    }

}

class Generic<@MyAnnotation(value = "hi") T>{
    public void show() throws @MyAnnotation RuntimeException{
        ArrayList<@MyAnnotation String> list=new ArrayList();
        int num=(@MyAnnotation int)10L;
    }
}
